package com.hbnrtech.sip.gb28181;

import com.hbnrtech.sip.gb28181.config.SipConfigProperties;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

import javax.annotation.PreDestroy;
import javax.sip.*;
import java.util.TooManyListenersException;

/**
 * @author liuduo
 * @date 2025-04-21 14:26
 */
@Component
@Slf4j
@Data
public class SipLayer implements CommandLineRunner {
    @Autowired
    private SipConfigProperties sipConfigProperties;
    @Autowired
    private SipStack sipStack;
    @Autowired
    private SipListener sipListener;

    private SipProvider udpProvider;
    private SipProvider tcpProvider;

    @Override
    public void run(String... args) {
        try {
            // --- 创建并添加 UDP 监听点 ---
            ListeningPoint udpListeningPoint = sipStack.createListeningPoint(
                    sipConfigProperties.getIp(),
                    sipConfigProperties.getPort(),
                    "UDP");
            this.udpProvider = sipStack.createSipProvider(udpListeningPoint);
            this.udpProvider.addSipListener(sipListener); // 注册监听器
            log.info("SIP UDP Listener started on {}:{}", sipConfigProperties.getIp(), sipConfigProperties.getPort());

            // 创建并添加 TCP 监听点 ---
            ListeningPoint tcpListeningPoint = sipStack.createListeningPoint(
                    sipConfigProperties.getIp(),
                    sipConfigProperties.getPort(),
                    "TCP");
            this.tcpProvider = sipStack.createSipProvider(tcpListeningPoint);
            this.tcpProvider.addSipListener(sipListener);
            log.info("SIP TCP Listener started on {}:{}", sipConfigProperties.getIp(), sipConfigProperties.getPort());

            sipStack.start();
            log.info("SIP Stack started successfully.");

        } catch (InvalidArgumentException | TooManyListenersException | SipException e) {
            log.error("Failed to start SIP Stack or Listening Points", e);
            // 实际应用中可能需要更复杂的错误处理，例如停止应用
            throw new RuntimeException("SIP Stack initialization failed", e);
        }
    }

    @PreDestroy // 在应用关闭前执行清理
    public void stopSipStack() {
        if (sipStack != null) {
            try {
                // 移除监听器和 Provider
                if (udpProvider != null) {
                    sipStack.deleteSipProvider(udpProvider);
                    sipStack.deleteListeningPoint(udpProvider.getListeningPoint("UDP"));
                    log.info("SIP UDP Listener stopped.");
                }
                if (tcpProvider != null) {
                    sipStack.deleteSipProvider(tcpProvider);
                    sipStack.deleteListeningPoint(tcpProvider.getListeningPoint("TCP"));
                    log.info("SIP TCP Listener stopped.");
                }

                sipStack.stop();
                log.info("SIP Stack stopped.");
            } catch (ObjectInUseException e) {
                log.error("Error stopping SIP Stack", e);
            }
        }
    }

    public SipProvider getSipProvider(String transport) {
        if ("udp".equalsIgnoreCase(transport)) {
            return udpProvider;
        } else if ("tcp".equalsIgnoreCase(transport)) {
            return tcpProvider;
        } else {
            throw new IllegalArgumentException("Unsupported transport: " + transport);
        }
    }
}
